package com.hzvdvmc.autosale.socket.manager;

import android.telephony.SignalStrength;
import android.text.TextUtils;

import com.hzvdvmc.autosale.constant.CmdEnum;
import com.hzvdvmc.autosale.constant.GlobleCache;
import com.hzvdvmc.autosale.constant.ResultEnum;
import com.hzvdvmc.autosale.constant.TimeConstant;
import com.hzvdvmc.autosale.socket.SocketClientManager;
import com.hzvdvmc.autosale.socket.TempDataHelper;
import com.hzvdvmc.autosale.sale.bean.BracketBean;
import com.hzvdvmc.autosale.socket.TempetureUtil;
import com.hzvdvmc.autosale.socket.event.CommonEvent;
import com.hzvdvmc.autosale.socket.event.TipEvent;
import com.hzvdvmc.autosale.util.EncodeUtil;
import com.hzvdvmc.autosale.util.LogUtil;
import com.hzvdvmc.autosale.util.MachineUtil;
import com.hzvdvmc.autosale.util.NetworkUtils;
import com.hzvdvmc.autosale.util.StringUtil;
import com.hzvdvmc.autosale.util.ToastUtils;
import com.vilyever.socketclient.SocketClient;

import org.greenrobot.eventbus.EventBus;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static com.hzvdvmc.autosale.constant.CmdEnum.KEEP_LIVE;
import static com.hzvdvmc.autosale.socket.manager.CheckNumUtil.getCheckNum;

/**
 * Created by william on 2017/12/13.
 * 指令发送 处理
 */

public class CmdRequestManager {
    public static CmdRequestManager instance;

    public static CmdRequestManager getInstance() {
        if (instance == null) {
            instance = new CmdRequestManager();
        }
        return instance;
    }

    private CmdRequestManager() {
    }

    private SocketClient getSocketClient() {
        return SocketClientManager.getInstance().getSocketClient();
    }



    /**
     * 发送数据
     */
    public void sendComand(CmdEnum cmd, String data) {
        if (!NetworkUtils.isConnected()) {
            ToastUtils.showShort("网络未连接");
            return;
        }

        if (getSocketClient() == null) {
            ToastUtils.showShort("连接初始化异常");
            return;
        }

        if (!getSocketClient().isConnected()) {
            ToastUtils.showShort("连接异常");
            return;
        }

        String fullCmd = null;
        if (cmd == KEEP_LIVE) {
            fullCmd = KEEP_LIVE.getValue();
        } else {
            fullCmd = getFullCommand(cmd, data);
        }

        if (TextUtils.isEmpty(fullCmd)) {
            ToastUtils.showShort("指令有误");
        }

        LogUtil.i("[request] 发送指令：" + fullCmd);
        LogUtil.p("[request] 发送指令：" + cmd.getDesc());
        getSocketClient().sendData(StringUtil.hexStringToBytes(fullCmd));
    }

    /**
     * 获取包头
     *
     * @param command
     * @param data
     * @return
     */
    private String getHeader(CmdEnum command, String data) {
        String start = CmdEnum.START.getValue();
        String size = Integer.toHexString(data.length() + 1);
        //size是2个字节，也就是4位16进制
        //比如10进制16 那就是 000F,10进制4096 那就是0FFF
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4 - size.length(); i++) {
            sb.append("0");
        }
        size = sb.toString() + size;
        String checkNum = getCheckNum(command.getValue(), data);
        return start + size + checkNum;
    }

    /**
     * 小数补零操作
     */
    private static String littleZero(String src) {
        if (src.length() == 2) {
            return src;
        } else {
            return src + "0";
        }
    }

    /**
     * 完整上传数据
     *
     * @param command 指令
     * @param data    中间的有效数据，需要转化成16进制
     * @return
     */
    private String getFullCommand(CmdEnum command, String data) {
        LogUtil.p("socket 请求指令：" + command.getDesc());
        StringBuilder sb = new StringBuilder();
        sb.append(getHeader(command, data));
        //消息体command+data
        String bodyMsg = EncodeUtil.encoded(command.getValue() + StringUtil.convertStringToHex(data));
        sb.append(bodyMsg);
        sb.append(CmdEnum.END.getValue());
        String fullComand = sb.toString();
        LogUtil.i("【reqeust】 " + command.getDesc());
        return fullComand;
    }

    /**
     * 心跳的完整指令
     *
     * @return
     */
    public String getHeartBeatCommandStr() {
        String deviceNO = MachineUtil.getDeviceNO();
        String netStrength = MachineUtil.getNetStrength();
        String temp = TempetureUtil.getCurrentTem();
        String doorState = MachineUtil.getDoorState();
        String data = deviceNO + netStrength + temp + doorState;
        return getFullCommand(CmdEnum.HEARTBEAT, data);
    }


    public void heartBeatRequest() {
        //心跳有修改
        String netStrong = "";
        String tempeture = "";
        String door = "";
        String data = MachineUtil.getDeviceNO() + netStrong + tempeture + door;
        sendComand(CmdEnum.HEARTBEAT, MachineUtil.getDeviceNO());
    }

    /**
     * 保活请求
     */
    public void keepLiveRequest() {
        sendComand(CmdEnum.KEEP_LIVE, null);
    }


    private boolean isSigning = false;
    /**
     * 签到请求
     */
    public void applySignRequest() {

        if (isSigning){
            return;
        }


        if (GlobleCache.isSign) {
            return;
        }

        isSigning = true;

        LogUtil.i("发起申请签到");
        SocketRequest request = new SocketRequest(CmdEnum.APPLY_SIGN);
        request.equence(MachineUtil.getDeviceNO(), new SocketLisenter() {
            @Override
            public void onResponse(String response,String tuneNO, String orderNO) {
                LogUtil.i("申请签到 响应成功");
                isSigning = false;
                String verificationCode = response.substring(12);
                signRequest(verificationCode);
            }

            @Override
            public void onError(String data) {
                LogUtil.i("申请签到 响应失败");
                isSigning = false;
//                ToastUtils.showShort("申请签到失败：" + data);
                //重新申请
                applySignRequest();
            }
        });
    }


    /**
     * 签到
     *
     * @param veriCode
     */
    private void signRequest(final String veriCode) {
        SocketRequest request = new SocketRequest(CmdEnum.SIGN);

        request.equence(MachineUtil.getDeviceNO() + veriCode, new SocketLisenter() {
            @Override
            public void onResponse(String response,String tuneNO, String orderNO) {
                String time = response.substring(0, 14);
                String result = response.substring(14);
                LogUtil.i("签到结果:" + result);

                if (ResultEnum.Success.getValue().equals(result)) {
                    GlobleCache.isSign = true;
                    EventBus.getDefault().post(new CommonEvent(CommonEvent.SIGN_SUCCESS));
                    ToastUtils.showShort("签到成功");
                    CmdRequestManager.getInstance().heartBeatRequest();
                } else {
                    //重新签到
                    applySignRequest();
                }
            }

            @Override
            public void onError(String data) {
                applySignRequest();
            }
        });
    }

    public void paySuccessAnswerRequest(boolean isSuccess) {
        String result = "1";
        if (isSuccess) {
            result = "0";
        }
        if (GlobleCache.isSign) {
            String data = MachineUtil.getDeviceNO() + result;
            sendComand(CmdEnum.PAY_SUCCESS, data);
        }
    }

    public String getSuccessVeriCmdData(String orderNO) {
        return MachineUtil.getDeviceNO() + orderNO;
    }

    /**
     * 通用验证请求
     */
    public void commonVeriRequest(CmdEnum cmd) {
        sendComand(cmd, MachineUtil.getDeviceNO());
        EventBus.getDefault().post(new TipEvent(cmd.getDesc() + "验证..."));
    }

    /**
     * 上报出货结果
     *
     * @param result  出货结果，若为null,则取上次的结果
     * @param orderNO
     */
    public String getResultReportCmdData(String result, String orderNO) {
        return MachineUtil.getDeviceNO() + orderNO + result;
        //缓存数据置空
    }

    /**
     * 通用应答
     *
     * @param cmd       指令标识
     * @param isSuccess 是否成功
     */
    public void commonAnswer(CmdEnum cmd, boolean isSuccess) {
        String result = "1";
        if (isSuccess) {
            result = "0";
        }
        if (GlobleCache.isSign) {
            String data = MachineUtil.getDeviceNO() + result;
            sendComand(cmd, data);
        }
    }

}
